package com.example.demo.service.impl;

/**
 * elasticsearch_demo
 * 2019/12/5 16:19
 *
 * @author
 * @description
 **/

import com.alibaba.fastjson.JSONObject;
import com.example.demo.dao.ElasticRepository;
import com.example.demo.domain.DocBean;
import com.example.demo.service.ElasticService;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.common.text.Text;
import org.elasticsearch.index.query.QueryStringQueryBuilder;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightBuilder;
import org.elasticsearch.search.fetch.subphase.highlight.HighlightField;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.domain.Pageable;
import org.springframework.data.elasticsearch.core.ElasticsearchRestTemplate;
import org.springframework.data.elasticsearch.core.SearchResultMapper;
import org.springframework.data.elasticsearch.core.aggregation.AggregatedPage;
import org.springframework.data.elasticsearch.core.aggregation.impl.AggregatedPageImpl;
import org.springframework.data.elasticsearch.core.query.NativeSearchQueryBuilder;
import org.springframework.data.elasticsearch.core.query.SearchQuery;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

@Service("elasticService")
public class ElasticServiceImpl implements ElasticService {

    @Autowired
    private ElasticsearchRestTemplate elasticsearchTemplate;
    @Autowired
    private ElasticRepository elasticRepository;

    private Pageable pageable = PageRequest.of(0, 10);

    @Override
    public void createIndex() {
        elasticsearchTemplate.createIndex(DocBean.class);
        //实体类注解后，此处需要添加mapping，不然分词不生效
        elasticsearchTemplate.putMapping(DocBean.class);
    }

    @Override
    public void deleteIndex(String index) {
        elasticsearchTemplate.deleteIndex(index);
    }

    @Override
    public void save(DocBean docBean) {
        elasticRepository.save(docBean);
    }

    @Override
    public void saveAll(List<DocBean> list) {
        elasticRepository.saveAll(list);
    }

    @Override
    public Iterator<DocBean> findAll() {
        return elasticRepository.findAll().iterator();
    }

//    @Override
//    public Page<DocBean> findByContent(String content) {
//        return elasticRepository.findByContent(content, pageable);
//    }

    @Override
    public Page<DocBean> findByFirstCode(String firstCode) {
        return elasticRepository.findByFirstCode(firstCode, pageable);
    }

    @Override
    public Page<DocBean> findBySecondCode(String SecondCode) {
        return elasticRepository.findBySecondCode(SecondCode, pageable);
    }


    @Override
    public Page<DocBean> findByContent(String content) {

        // 定义高亮字段
        HighlightBuilder.Field contentField = new HighlightBuilder.Field("content").preTags("<span>").postTags("</span>");
        // 构建查询内容
        QueryStringQueryBuilder queryBuilder = new QueryStringQueryBuilder(content);
        // 查询匹配的字段
        queryBuilder.field("content");

        SearchQuery searchQuery = new NativeSearchQueryBuilder().withQuery(queryBuilder)
                .withHighlightFields(contentField).build();
        long count = elasticsearchTemplate.count(searchQuery, DocBean.class);
        System.out.println("系统查询个数：--》" + count);
        if (count == 0) {
            return null;
        }
        //需要的话可以实现分页效果，注意，页面是从 0 开始
        //Query query = searchQuery.setPageable(new PageRequest(0, (int) count));

        AggregatedPage<DocBean> queryForPage = elasticsearchTemplate.queryForPage(searchQuery, DocBean.class,
                new SearchResultMapper() {

                    @Override
                    public <T> AggregatedPage<T> mapResults(SearchResponse response, Class<T> clazz,
                                                            Pageable pageable) {

                        List<DocBean> list = new ArrayList<DocBean>();
                        for (SearchHit searchHit : response.getHits()) {
                            if (response.getHits().getHits().length <= 0) {
                                return null;
                            }
                            DocBean DocBean = JSONObject.parseObject(searchHit.getSourceAsString(), DocBean.class);
                            Map<String, HighlightField> highlightFields = searchHit.getHighlightFields();
                            //匹配到的content字段里面的信息
                            HighlightField contentHighlight = highlightFields.get("content");
                            if (contentHighlight != null) {
                                Text[] fragments = contentHighlight.fragments();
                                String fragmentString = fragments[0].string();
                                DocBean.setContent(fragmentString);
                            }
                            list.add(DocBean);

                        }
                        if (list.size() > 0) {
                            return new AggregatedPageImpl<T>((List<T>) list);
                        }
                        return null;
                    }

                    @Override
                    public <T> T mapSearchHit(SearchHit searchHit, Class<T> aClass) {
                        return null;
                    }
                });
//        List<DocBean> list = queryForPage.getContent();

        return queryForPage;
    }
}   


